<template>
  <page-card title="菜单管理"
             sub-title="编辑"
             :need-back="true">
    <a-form-model :model="form"
                  :label-col="{ span: 6 }"
                  :wrapper-col="{ span: 12 }"
                  ref="form"
                  :rules="{
                    name: [{required: true, message:'此项必填'}],
                    code: [{required: true, message:'此项必填'}],
                    orderNo: [{required: true, message: '此项必填'}],
                    uri: [{
                      validator: validateURI, trigger: 'blur'
                    }],
                    category: [{ required: true, message:'此项必填' }]
                  }">
      <a-form-model-item label="上级菜单">
        <span>{{ parentName }}</span>
        <a href="javascript:;;"
           @click="popupVisible=true">
          <a-icon type="edit"
                  style="font-size: var(--font-size-18); margin-left: 10px;"
                  theme="filled" />
        </a>
        <a-modal :visible="popupVisible"
                 title="上级菜单"
                 @ok="popupVisible=false"
                 @cancel="popupVisible=false">
          <a-cascader @popupVisibleChange="onPopupVisibleChange"
                      placeholder="请选择"
                      style="width: 100%;"
                      :show-search="{ filter }"
                      @change="onParentChange"
                      ref="parentCascader"
                      :fieldNames="{label:'name', value:'id', children: 'children'}"
                      :changeOnSelect="true"
                      :options="parentTreeData">
          </a-cascader>
        </a-modal>
      </a-form-model-item>
      <a-form-model-item label="名称"
                         prop="name">
        <a-input v-model.trim="form.name"
                 :maxLength="20"
                 placeholder="不超过20字">
          <a href="javascript:;;"
             slot="suffix"
             @click="menuPopupVisible=true">
            <a-icon style="cursor: pointer; font-size: var(--font-size-18)"
                    type="edit"
                    theme="filled" />
          </a>
        </a-input>
        <a-modal :visible="menuPopupVisible"
                 title="名称"
                 @ok="menuPopupVisible=false"
                 @cancel="menuPopupVisible=false">
          <a-cascader style="width: 100%;"
                      placeholder="请选择"
                      :show-search="{ filter }"
                      @popupVisibleChange="onMenuPopupVisibleChange"
                      :changeOnSelect="true"
                      @change="onMenuSelected"
                      ref="menuCascader"
                      :fieldNames="{label:'title', value:'level', children: 'children'}"
                      :options="menuTreeDataList">
          </a-cascader>
        </a-modal>
      </a-form-model-item>
      <a-form-model-item v-show="this.selectedParentList.length==0"
                         label="分类"
                         :prop="this.selectedParentList.length==0?'category':''">
        <a-radio-group v-model="form.category"
                       :options="[{
                         label: '管理端', value: '1'
                       }, {
                         label: '用户端', value: '2'
                       }]" />
      </a-form-model-item>
      <a-form-model-item label="类型"
                         help="配置该功能菜单的增删改查，选择功能选项"
                         prop="type">
        <a-radio-group v-model="form.type"
                       :options="[
                         { label: '分类', value: '1' },
                         { label: '菜单', value: '2' },
                         { label: '功能', value: '3' }]"
                       @change="onTypeChange" />
      </a-form-model-item>
      <a-form-model-item label="打开方式">
        <a-radio-group v-model="form.target"
                       :options="[{
                         label: '本应用', value: '1'
                       }, {
                         label: '内嵌', value: '2'
                       }, {
                         label: '新窗口', value: '3'
                       }]" />
      </a-form-model-item>
      <a-form-model-item label="编码"
                         help="只能包含字母、数字、减号或下划线"
                         prop="code">
        <a-input v-model.trim="form.code"
                 :addon-before="parentCode"
                 @change="onCodeChange"
                 :maxLength="120" />
      </a-form-model-item>
      <a-form-model-item label="PC端地址"
                         help="PC端路由地址，例：/dowork"
                         prop="uri">
        <a-input v-model="form.uri"
                 :maxLength="30"
                 :isEdit="false"
                 placeholder="只能包含字母, 数字, 减号, 下划线, ?, &, =, /:，一般与编码保持一致即可"
                 ref="uriField" />
      </a-form-model-item>
      <a-form-model-item label="移动端地址">
        <a-input v-model="form.mobileUrl"
                 :maxLength="200"
                 placeholder="不超过200个字符">
          <a-cascader slot="suffix"
                      @popupVisibleChange="onMobilePopupVisibleChange"
                      :changeOnSelect="true"
                      @change="onMobileRouteSelected"
                      ref="mobileCascader"
                      :fieldNames="{label:'title', value:'_level', children: 'children'}"
                      :options="mobileRouteList">
            <a href="javascript:;;">
              <a-icon style="cursor: pointer; font-size: var(--font-size-18)"
                      type="edit"
                      theme="filled" />
            </a>
          </a-cascader>
        </a-input>
      </a-form-model-item>
      <a-form-model-item label="应用编码">
        <a-select v-model="form.appCode"
                  style="width: 100%"
                  allowClear
                  placeholder="请选择">
          <a-select-option :value="item.code"
                           :key="index"
                           v-for="(item, index) in appList">
            {{ item.name }}
          </a-select-option>
        </a-select>
      </a-form-model-item>
      <a-form-model-item label="图标"
                         v-if="!form.parentId||form.parentId=='0'">
        <MenuIcon @handelMenuIcon="getMenuIcon"
                  v-model="form.icon"
                  :imgSize="imgSize"
                  ref="choseIcon">
        </MenuIcon>
      </a-form-model-item>
      <a-form-model-item label="排序号"
                         prop="orderNo">
        <a-input-number v-model="form.orderNo"
                        :min="1"
                        :max="10000" />
      </a-form-model-item>
      <a-form-model-item v-if="form.type != '3'"
                         label="是否隐藏"
                         help="是否在左侧菜单栏隐藏该菜单">
        <z-switch-one-zero v-model="form.hidden"
                           checked-children="是"
                           un-checked-children="否" />
      </a-form-model-item>
      <a-form-model-item label="是否启用">
        <z-switch-one-zero v-model="form.status"
                           checked-children="是"
                           un-checked-children="否" />
      </a-form-model-item>
      <a-form-model-item label="说明">
        <a-textarea :maxLength="120"
                    placeholder="菜单功能描述，不超过120字"
                    v-model="form.remark"
                    style="height:100px" />
      </a-form-model-item>
    </a-form-model>
    <div style="text-align:center">
      <a-button type="primary"
                action
                @click="handleSave"
                style="width:80px;">
        保存
      </a-button>
    </div>
  </page-card>
</template>

<script>
import MenuIcon from './components/MenuIcon.vue'
// 1、引入Vue等框架组件库或插件
import clone from 'clone'
// 2、引入自定义组件
// 3、引入第三方工具类插件
// 4、引入自定义工具或插件或混入或基类等
import ArrayUtil from '@zh/common-utils/utils/array'

// 5、引入API
import { saveOrUpdate, getById, getParentsById, getAll, getAppList } from '../../api/menu/index'

export default {
  components: { MenuIcon },
  data () {
    return {
      popupVisible: false,
      menuPopupVisible: false,
      appPopupVisible: false,
      form: {
        type: '2',
        name: '',
        code: '',
        orderNo: '',
        category: '1',
        target: '1',
        status: '1',
        appCode: '',
        uri: '',
        component: '',
        hidden: '0',
        mobileUrl: ''
      },
      selectedParentList: [],
      parentTreeData: [],
      parentName: '',
      visible: false,
      menuTreeData: [],
      mobileRouteList: [],
      appList: [],
      selectedMenu: null,
      selectedMobileRoute: null,
      parentCode: '',
      // 已选择的应用图标
      uploadIcon: '',
      imgSize: 50
    }
  },
  watch: {
    selectedParentList () {
      const parentMenu = this.selectedParentList[this.selectedParentList.length - 1]
      this.parentName = this.selectedParentList.map(p => p.name).join(' / ') || '无'
      if (parentMenu) {
        this.form.parentId = parentMenu.id
        this.form.category = parentMenu.category
      }
      this.parentCode = this.selectedParentList.map(item => item.code.split(':').pop()).join(':') + ':'
    },
    selectedMenu () {
      if (!this.selectedMenu) {
        this.form.path = ''
        this.form.name = ''
        this.form.code = ''
        this.form.uri = ''
        this.form.type = '2'
      } else {
        this.form.uri = this.selectedMenu.path || ''
        this.form.name = this.selectedMenu.title || ''
        this.form.code = this.selectedMenu.meta.code || ''
        this.form.target = this.selectedMenu.meta.target || '1'
        this.selectedMenu.meta.code && (this.form.type = '3')
      }
    }
  },
  computed: {
    menuTreeDataList () {
      if (this.selectedParentList?.length > 0) {
        const selectedParent = this.selectedParentList[this.selectedParentList.length - 1]
        if (selectedParent.code && selectedParent.code.indexOf(':') != -1) {
          // this.form.code = selectedParent.code.split(':').pop()
          // return this.menuTreeData
          // return this.menuTreeData.filter(item => item.path && item.path.startsWith(`/${code}`))
          // } else {
          // return this.menuTreeData
          // return []
        }
      } else {
        // return this.menuTreeData
        // return []
      }
      return this.menuTreeData
    }
    // parentCode () {
    //   // return `${this.parentCodes.join(':')}:`
    //   return ''
    // }
  },
  mounted () {
    // 初始化本地菜单配置信息
    this.initLocalRouteConfig()
    // 初始化应用管理信息
    this.initAppList()
    // 初始化本地移动端路由菜单配置信息
    this.initLocalMobileRouteTree()

    const params = this.$route.query
    if (params.parentId || (!params.id && !params.parentId)) {
      // 新增获取所有上级节点
      // this.parentCodes = []
      getParentsById(params.parentId || '').then(response => {
        if (!this.$route.query.id) {
          this.form.orderNo = response.orderNo
        }
        response.parentMenuList = response.parentMenuList.map(data => {
          return {
            id: data.id,
            parentId: data.parentId,
            target: data.target,
            type: data.type,
            uri: data.uri,
            name: data.name,
            code: data.code,
            icon: data.icon,
            hidden: data.hidden
          }
        })
        this.selectedParentList = response.parentMenuList
        this.initParentTreeData()
      })
    }
    if (params.id) {
      // 编辑获取数据
      getById(params.id).then(response => {
        this.selectedParentList = response.parentMenuList
        this.parentCodes = []
        response.parentMenuList = response.parentMenuList.map(data => {
          this.parentCodes.push(data.code.split(':').pop())
          return {
            id: data.id,
            parentId: data.parentId,
            target: data.target,
            type: data.type,
            uri: data.uri,
            name: data.name,
            code: data.code,
            icon: data.icon,
            hidden: data.hidden
          }
        })
        this.parentTreeData = response.parentMenuList
        response.uri = response.uri || ''
        if (response.uri.startsWith('http://')) {
          this.uriType = 'http://'
          response.uri = response.uri.replace(this.uriType, '')
        } else if (response.uri.startsWith('https://')) {
          this.uriType = 'https://'
          response.uri = response.uri.replace(this.uriType, '')
        } else {
          this.uriType = this.parentURI
          response.uri = response.uri.replace(this.parentURI, '')
          // response.uri.startsWith('/') && (response.uri = response.uri.substring(1))
        }
        response.code = response.code.split(':').pop()
        this.form = response

        this.initParentTreeData()
      })
    }
  },
  methods: {
    // 选择的图标数据
    getMenuIcon (res) {
      this.uploadIcon = res
    },
    onPopupVisibleChange (isPopupVisible) {
      if (!isPopupVisible) {
        if (this.$refs.parentCascader?.parents?.length > 0) {
          this.selectedParentList = this.$refs.parentCascader.parents
        }
      }
    },
    onMenuPopupVisibleChange (isPopupVisible) {
      if (!isPopupVisible) {
        if (this.$refs.menuCascader?.selectedList?.length > 0) {
          this.selectedMenu = this.$refs.menuCascader.selectedList[this.$refs.menuCascader.selectedList.length - 1]
        }
      }
    },
    onMenuSelected (keys, nodeDataList) {
      this.$refs.menuCascader.selectedList = nodeDataList
    },
    onMobilePopupVisibleChange (isPopupVisible) {
      if (!isPopupVisible) {
        if (this.$refs.mobileCascader?.selectedList?.length > 0) {
          const selectedMobileRoute = this.$refs.mobileCascader.selectedList[this.$refs.mobileCascader.selectedList.length - 1]
          this.form.mobileUrl = selectedMobileRoute.path
          this.form.category = '2'
        }
      }
    },
    onMobileRouteSelected (keys, nodeDataList) {
      this.$refs.mobileCascader.selectedList = nodeDataList
    },
    onParentChange (keys, nodeDataList) {
      this.$refs.parentCascader.parents = nodeDataList
    },
    onTypeChange () {
      if (this.form.type == '3') {
        this.form.hidden = '1'
      }
    },
    initParentTreeData () {
      getAll().then((response) => {
        const excludeParentIds = [], ids = [], map = {}, dataList = []
        response.map((i) => {
          if (i.type == '3') {
            return
          }
          i.parentId == '0' && (i.parentId = null)
          i.value = i.id
          i.label = i.name
          ids.push(i.id)
          map[i.id] = {
            id: i.id,
            parentId: i.parentId,
            name: i.name,
            code: i.code,
            category: i.category,
            target: i.target,
            uri: i.uri
          }
        })
        ids.map(id => {
          // 排除本节点及其以下所有节点
          id == this.form.id && excludeParentIds.push(id)
          if (excludeParentIds.includes(map[id].parentId)) {
            excludeParentIds.push(id)
          }
          !excludeParentIds.includes(id) && dataList.push(map[id])
        })
        const { nodeList } = ArrayUtil.toTree(dataList, 'id', 'parentId')
        nodeList.splice(0, 0, {
          id: '0',
          parentId: null,
          name: '无',
          code: '',
          category: null,
          target: '1',
          uri: ''
        })
        this.parentTreeData = nodeList
      })
    },
    initLocalRouteConfig () {
      const menuTreeData = this.$router.getRouteConfig('pc').filter(route => !route._parent).sort((r1, r2) => {
        if (r1.meta.title > r2.meta.title) {
          return -1
        } else if (r1.meta.title < r2.meta.title) {
          return 1
        }
        return 0
      })
      this.menuTreeData = menuTreeData.map((data, index) => {
        return this.rebuildMenuTreeData(data, index)
      })
    },
    initAppList () {
      getAppList().then(response => {
        this.appList = response
      })
    },
    rebuildMenuTreeData (data, index, parentlevel = '0') {
      data.title = data.meta.title
      data.level = `${parentlevel}-${index}`
      if (data.children) {
        let children = [], index = -1
        index = data.children.findIndex(item => item.meta?.code == 'add')
        index != -1 && children.push(data.children.splice(index, 1)[0])

        index = data.children.findIndex(item => item.meta?.code == 'edit')
        index != -1 && children.push(data.children.splice(index, 1)[0])

        index = data.children.findIndex(item => item.meta?.code == 'delete')
        index != -1 && children.push(data.children.splice(index, 1)[0])

        data.children = [...children, ...data.children].map((child, idx) => {
          return this.rebuildMenuTreeData(child, idx, data.level)
        })
      }

      return data
    },
    /**
     * 初始化移动端路由数据结构
     */
    initLocalMobileRouteTree () {
      const mobileRouteList = this.$router.getRouteConfig('mobile').filter(route => !route._parent).sort((r1, r2) => {
        if (r1.meta.title > r2.meta.title) {
          return -1
        } else if (r1.meta.title < r2.meta.title) {
          return 1
        }
        return 0
      })
      this.mobileRouteList = mobileRouteList.map((data, index) => {
        return this.rebuildMenuTreeData(data, index)
      })
    },
    onCodeChange (e) {
      if (this.form.target != 1) {
        return
      }
      e.target.value = e.target.value.replace(/[`~!@#$%^&*()+=<>?:"{}|,./;'\\[\]·~！@#￥%……&*（）——+={}|《》？：“”【】、；‘’，。、]/g, '').replace(/\s/g, '')
      this.form.code = e.target.value
    },
    validateURI (rule, value, callback) {
      callback()
    },
    handleSave () {
      this.$refs.form.validate(ok => {
        if (!ok) {
          return
        }
        this.form.icon = this.uploadIcon
        const formData = { ...this.form }
        formData.code = `${this.parentCode}${formData.code}`.replace(/^:+/, '')
        saveOrUpdate(formData).then((response) => {
          this.$router.go(-1)
        })
      })
    }
  }
}
</script>

<style lang="less" scoped>
</style>